<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <link rel="shortcut icon" href="../img/favicon.ico" type="image/x-icon">
  <link rel="stylesheet" href="../css/style.css">
  <title>变化侦测相关的API实现原理</title>
</head>
<body>
  <img src="../img/vm-api-global.png" alt="">
  <h2>变化侦测相关的API实现原理</h2>
  <h3>vm.$watch(expOrFn, callback, [options])</h3>
  <li>expOrFn可以是一个以点分割的路径，或者是一个函数表达式</li>
  <li>返回一个取消观察的函数，用来停止触发回调</li>
  <li>options.deep同事监测内部值的变化</li>
  <li>options.immediate如果设置为true,将立即以<span>表达式的当前值</span>触发回调</li>
  <li>
    原理：将参数传入new Watcher()。-》执行Constructor函数，读取自身state添加入getter。-》状态变化时，在回调函数中接受新值与旧值。(<span>传入的回调函数只是接受了新旧值，状态引发的更新时在VuJS内部进行的更新</span>)
  </li>
  <li>
    当expOrFn是函数的时候，VueJs会同时观察函数中读取到的所有VueJS实例上的响应式数据，计算属性Computed的实现原理跟expOrFn支持函数有很大关系
  </li>
  <li>
    deep实现原理： 被监听对象的子值循环触发了一遍getter,从而触发了收集watchers逻辑
  </li>

  <h3>vm.$set(target. key. value)</h3>
  <li>
    用法：在object上设置一个属性，如果object时响应式的，Vue.js会保证属性被创建后也是响应式的，并且触发视图更新
  </li>
  <li>
    <span>Array的处理</span>： 通过target.splice()设置对应的值，这时候拦截器会接收到通知并<span>自动</span>触发更新
  </li>
  <li>
    <h4>Object的处理</h4>
    <li>
      已存在的属性，相当于重新设置值：说明这个值之前已经被侦测到了变化，直接修改值就行。target[key]=val
    </li>
    <li>
      之前不存在的值，相当于新增： 判断target之前是不是响应式对象(targrt.__ob__属性) ->Y ->definedProperty and dep.nodify() -> N -> targrt[key]=val and return <span>target.__ob__属性是在New Observer的时候添加的</span>
    </li>
  </li>

  <h4>vm.$delete(target, val)</h4>
  <li>
    原理：调用原生delete,并触发dep.nodify()
  </li>
</body>
</html>